package lib.paxos;

import java.io.Serializable;
import java.util.List;

import lib.ArgumentValidator;
import lib.messaging.NetworkAddress;

/**
 * Representation of ack for a prepare message
 * @author abhip
 *
 */
public class AckMessage implements Serializable
{
    /**
     * serialVersionUID is a universal version identifier for a Serializable
     * class. Deserialization uses this number to ensure that a loaded class
     * corresponds exactly to a serialized object. If no match is found during
     * deserialization, an InvalidClassException is thrown.
     */
    private static final long serialVersionUID = 6887337476657122653L;

    private AcceptMessage acceptedMessage;
    private int currentRoundID;
    private SequenceID highestKnownSeqID;
    private boolean isProposerPartOfEpoch;
    private List<RoundInfo> missingRoundInfos;
    private NetworkAddress senderAddress;

    public AckMessage(
            NetworkAddress address,
            int currentRoundID,
            SequenceID highestKnownSeqID,
            AcceptMessage acceptedMessage,
            List<RoundInfo> missingRoundInfos,
            boolean isProposerPartOfEpoch)
    {
        ArgumentValidator.IsNotNull("address", address);
        ArgumentValidator.IsGreaterThanOrEqualTo("currentRoundID", currentRoundID, 0);
        // rest parameters can be null depending on the situation

        this.senderAddress = address;
        this.currentRoundID = currentRoundID;
        this.highestKnownSeqID = highestKnownSeqID;
        this.acceptedMessage = acceptedMessage;
        this.missingRoundInfos = missingRoundInfos;
        this.isProposerPartOfEpoch = isProposerPartOfEpoch;
    }

    public AcceptMessage AcceptedMessage()
    {
        return acceptedMessage;
    }

    public int CurrentRoundID()
    {
        return currentRoundID;
    }

    public SequenceID HighestKnownSeqID()
    {
        return highestKnownSeqID;
    }

    public boolean IsProposerPartOfEpoch()
    {
        return isProposerPartOfEpoch;
    }

    public List<RoundInfo> MissingRoundInfos()
    {
        return missingRoundInfos;
    }

    public NetworkAddress SenderAddress()
    {
        return senderAddress;
    }

    @Override
	public String toString()
    {
    	StringBuilder missingRoundInfosSb = new StringBuilder();
    	if (missingRoundInfos != null)
    	{
	    	for (int i = 0; i < missingRoundInfos.size(); ++i)
	    	{
	    		missingRoundInfosSb.append(missingRoundInfos.get(i).toString());
	    	}
    	}

		return "AckMessage [senderAddress=" + senderAddress
				+ ", currentRoundID=" + currentRoundID + ", highestKnownSeqID="
				+ highestKnownSeqID + ", acceptedMessage=" + acceptedMessage
				+ ", missingRoundInfos=" + missingRoundInfosSb.toString() + "]";
	}
}
